// Released in the Public Domain. http://creativecommons.org/licenses/publicdomain/
package org.xi8ix.async.spi;

import java.nio.ByteBuffer;
import java.util.UUID;
import java.util.concurrent.*;

/**
 * A Future<Boolean> returned by the send() method allowing callers to cancel() the send or
 * get() the success status of the send operation. Used internally by the default implementations of
 * Server.
 *
 * @author Iain Shigeoka
 */
class SendFuture<T> implements Future<Boolean> {
    private ByteBuffer data;
    private T peer;
    private SendFutureSender sender;
    private UUID id;
    private long startTime;

    private boolean cancelled = false;
    private boolean done = false;
    private boolean success = false;
    private CountDownLatch successLatch = new CountDownLatch(1);

    public SendFuture(SendFutureSender sender, T peer, ByteBuffer data) {
        this.sender = sender;
        this.peer = peer;
        this.data = data;
        id = UUID.randomUUID();
        this.startTime = System.currentTimeMillis();
    }

    public ByteBuffer getData() {
        return data;
    }

    public T getPeer() {
        return peer;
    }

    public UUID getId() {
        return id;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setSuccess(boolean success) {
        this.success = success;
        successLatch.countDown();
    }

    public boolean cancel(boolean mayInterruptIfRunning) {
        sender.cancel(id);
        return cancelled;
    }

    public boolean isCancelled() {
        return cancelled;
    }

    public boolean isDone() {
        return done;
    }

    public Boolean get() throws InterruptedException, ExecutionException {
        successLatch.await();
        return success;
    }

    public Boolean get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        successLatch.await(timeout, unit);
        return success;
    }
}
